package cn.tedu.tickets;/**
 * @Author 金帮嘉诚 @Date 2021-06-23 星期三 11:06
 */
/*本类用于测试*/

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 知识点
 */
public class TestRunnableV2 {
    public static void main(String[] args) {
        TicketRunnableV2 my3 = new TicketRunnableV2();
//        Thread t1 = new Thread(my3);
//        Thread t2 = new Thread(my3);
//        Thread t3 = new Thread(my3);
//        Thread t4 = new Thread(my3);
//
//        t1.start();
//        t2.start();
//        t3.start();
//        t4.start();

        /*9.线程池ExecutorService：用于存储线程的池子，把新建/启动/关闭线程都交给池来做*/
        /*10.创建Executors：用于创建线程池的工具类，
        newFixedThreadPool(线程数)--创建一个指定线程数的线程池*/
        ExecutorService executorService = Executors.newFixedThreadPool(5);
        for (int i = 0; i < 5; i++) {
        /*10.executor()让线程池中的线程来执行任务，每次调用都会启动一个线程
        * 方法的参数是要执行的自定义业务，也就是目标对象*/
            executorService.execute(my3);

        }

    }
}
class TicketRunnableV2 implements Runnable {
    //用接口的方式，可以不用设置成静态
    int ticketNumber = 100;
    Object obj = new Object();

    //记住先写结构再填功能代码
    //流程要熟悉，有条理，才不容易出错，代码容易查看
    @Override
    public void run() {
        while (true) {
            //synchronized同步方法用的锁对象是this
            //或者是  当前类类名.class MyThread3.class
//            synchronized (MyThread3.class){字节码对象
            synchronized (obj) {//锁对象必须唯一，用Runnable接口，锁对象可以用obj
//            synchronized (this) {

                if (ticketNumber > 0) {
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    System.out.println("还剩" + ticketNumber-- + "张，售出一张");
                }
                if (ticketNumber <= 0) break;
            }
        }
        System.out.println("抱歉！票已售完！");

    }
}
